@@ -7,28 +7,31 @@ module Agents |
||
7 | 7 |
For example if you have an event like |
8 | 8 |
|
9 | 9 |
{ |
10 |
- :content => { |
|
11 |
- :text => "Lorem ipsum dolor sit amet" |
|
10 |
+ :high => { |
|
11 |
+ :celsius => "18", |
|
12 |
+ :fahreinheit => "64" |
|
12 | 13 |
}, |
13 |
- :fields => "consectetur adipisicing elit", |
|
14 |
+ :conditions => "Rain showers", |
|
14 | 15 |
:data => "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." |
15 | 16 |
} |
16 | 17 |
|
17 | 18 |
|
18 |
- And other agents which are receiving this event, say, Twilio Agent expects `message` key , and Digest Email Agent which expects a `subject` key, then you can reformat this event by filling `Options` in the following way. |
|
19 |
+ And other agents which are receiving this event, say, Twilio Agent expects `message` key , and Digest Email Agent which expects a `subject` key, then you can reformat this event by filling `Instructions` in the following way. |
|
19 | 20 |
|
20 |
- message => $.content.text |
|
21 |
- subject => $.fields |
|
21 |
+ message => "Today's conditions look like <$.conditions> and high temperaure is going to be <$.high.celsius> degree Celsius."" |
|
22 |
+ subject => "$.data" |
|
22 | 23 |
|
23 |
- Values must be provided in JSONPath. You can add as many keys as you like. |
|
24 |
+ JSONPaths must be between < and > . Make sure you dont use this symbols anywhere else. You can add as many keys as you like. |
|
24 | 25 |
|
25 |
- Then, event generated by Event Formatting Agent will be like |
|
26 |
+ Event generated by Event Formatting Agent will be like |
|
26 | 27 |
|
27 | 28 |
{ |
28 |
- :message => "Lorem ipsum dolor sit amet" |
|
29 |
- :subject => "consectetur adipisicing elit" |
|
29 |
+ :message => "Today's conditions look like Rain showers and high temperaure is going to be 18 degree Celsius" |
|
30 |
+ :subject => "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." |
|
30 | 31 |
} |
31 | 32 |
|
33 |
+ `Mode` can only be `merge` or `clean`. If you want to retain original contents of events and only add add new keys, then use `merge` mode else use `clean` mode. |
|
34 |
+ |
|
32 | 35 |
MD |
33 | 36 |
|
34 | 37 |
event_description <<-MD |
@@ -36,9 +39,18 @@ module Agents |
||
36 | 39 |
User defined |
37 | 40 |
MD |
38 | 41 |
|
42 |
+ def validate_options |
|
43 |
+ errors.add(:base,"instructions,mode,skip_agent and skip_created_at , all need to be present.") unless options[:instructions].present? and options[:mode].present? and options[:skip_agent].present? and options[:skip_created_at].present? |
|
44 |
+ end |
|
45 |
+ |
|
39 | 46 |
def default_options |
40 | 47 |
{ |
41 |
- :message => "$.data.fields.content" |
|
48 |
+ :instructions => { |
|
49 |
+ :message => "You received a text <$.text> from <$.fields.from>", |
|
50 |
+ :content => "Looks like the weather is going to be <$.fields.weather>"}, |
|
51 |
+ :mode => "clean", |
|
52 |
+ :skip_agent => "false", |
|
53 |
+ :skip_created_at => "false" |
|
42 | 54 |
} |
43 | 55 |
end |
44 | 56 |
|
@@ -46,14 +58,16 @@ module Agents |
||
46 | 58 |
true |
47 | 59 |
end |
48 | 60 |
|
61 |
+ def value_constructor(value,payload) |
|
62 |
+ value.gsub(/<[^>]+>/).each {|jsonpath| Utils.values_at(payload,jsonpath[1..-2]).first.to_s} |
|
63 |
+ end |
|
64 |
+ |
|
49 | 65 |
def receive(incoming_events) |
50 | 66 |
incoming_events.each do |event| |
51 |
- formatted_event = {} |
|
52 |
- options.each_pair do |key,value| |
|
53 |
- formatted_event[key] = Utils.values_at event.payload,value |
|
54 |
- end |
|
55 |
- formatted_event[:agent] = Agent.find(event.agent_id).type.slice! 8..-1 |
|
56 |
- formatted_event[:created_at] = event.created_at |
|
67 |
+ formatted_event = options[:mode].to_s == "merge" ? event.payload : {} |
|
68 |
+ options[:instructions].each_pair {|key,value| formatted_event[key] = value_constructor value, event.payload} |
|
69 |
+ formatted_event[:agent] = Agent.find(event.agent_id).type.slice!(8..-1) unless options[:skip_agent].to_s == "true" |
|
70 |
+ formatted_event[:created_at] = event.created_at unless options[:skip_created_at].to_s == "true" |
|
57 | 71 |
create_event :payload => formatted_event |
58 | 72 |
end |
59 | 73 |
end |
@@ -44,7 +44,8 @@ module Agents |
||
44 | 44 |
create_event :payload => {:content => content, |
45 | 45 |
:valence => sent_values[0], |
46 | 46 |
:arousal => sent_values[1], |
47 |
- :dominance => sent_values[2]} |
|
47 |
+ :dominance => sent_values[2], |
|
48 |
+ :original_event => event.payload} |
|
48 | 49 |
end |
49 | 50 |
end |
50 | 51 |
end |
@@ -0,0 +1,119 @@ |
||
1 |
+require 'spec_helper' |
|
2 |
+ |
|
3 |
+describe Agents::EventFormattingAgent do |
|
4 |
+ before do |
|
5 |
+ @valid_params = { |
|
6 |
+ :name => "somename", |
|
7 |
+ :options => { |
|
8 |
+ :instructions => { |
|
9 |
+ :message => "Received <$.content.text.*> from <$.content.name> .", |
|
10 |
+ :subject => "Weather looks like <$.conditions>" |
|
11 |
+ }, |
|
12 |
+ :mode => "clean", |
|
13 |
+ :skip_agent => "false", |
|
14 |
+ :skip_created_at => "false" |
|
15 |
+ } |
|
16 |
+ } |
|
17 |
+ @checker = Agents::EventFormattingAgent.new(@valid_params) |
|
18 |
+ @checker.user = users(:jane) |
|
19 |
+ @checker.save! |
|
20 |
+ |
|
21 |
+ @event = Event.new |
|
22 |
+ @event.agent = agents(:jane_weather_agent) |
|
23 |
+ @event.created_at = Time.now |
|
24 |
+ @event.payload = { |
|
25 |
+ :content => { |
|
26 |
+ :text => "Some Lorem Ipsum", |
|
27 |
+ :name => "somevalue" |
|
28 |
+ }, |
|
29 |
+ :conditions => "someothervalue" |
|
30 |
+ } |
|
31 |
+ end |
|
32 |
+ |
|
33 |
+ describe "#receive" do |
|
34 |
+ it "checks if clean mode is working fine" do |
|
35 |
+ @checker.receive([@event]) |
|
36 |
+ Event.last.payload[:content].should == nil |
|
37 |
+ end |
|
38 |
+ |
|
39 |
+ it "checks if merge mode is working fine" do |
|
40 |
+ @checker.options[:mode] = "merge" |
|
41 |
+ @checker.receive([@event]) |
|
42 |
+ Event.last.payload[:content].should_not == nil |
|
43 |
+ end |
|
44 |
+ |
|
45 |
+ it "checks if skip_agent is working fine" do |
|
46 |
+ @checker.receive([@event]) |
|
47 |
+ Event.last.payload[:agent].should == "WeatherAgent" |
|
48 |
+ @checker.options[:skip_agent] = "true" |
|
49 |
+ @checker.receive([@event]) |
|
50 |
+ Event.last.payload[:agent].should == nil |
|
51 |
+ end |
|
52 |
+ |
|
53 |
+ it "checks if skip_created_at is working fine" do |
|
54 |
+ @checker.receive([@event]) |
|
55 |
+ Event.last.payload[:created_at].should_not == nil |
|
56 |
+ @checker.options[:skip_created_at] = "true" |
|
57 |
+ @checker.receive([@event]) |
|
58 |
+ Event.last.payload[:created_at].should == nil |
|
59 |
+ end |
|
60 |
+ |
|
61 |
+ it "checks if instructions are working fine" do |
|
62 |
+ @checker.receive([@event]) |
|
63 |
+ Event.last.payload[:message].should == "Received Some Lorem Ipsum from somevalue ." |
|
64 |
+ Event.last.payload[:subject].should == "Weather looks like someothervalue" |
|
65 |
+ end |
|
66 |
+ |
|
67 |
+ it "checks if it can handle multiple events" do |
|
68 |
+ event1 = Event.new |
|
69 |
+ event1.agent = agents(:bob_weather_agent) |
|
70 |
+ event1.payload = { |
|
71 |
+ :content => { |
|
72 |
+ :text => "Some Lorem Ipsum", |
|
73 |
+ :name => "somevalue" |
|
74 |
+ }, |
|
75 |
+ :conditions => "someothervalue" |
|
76 |
+ } |
|
77 |
+ |
|
78 |
+ event2 = Event.new |
|
79 |
+ event2.agent = agents(:bob_weather_agent) |
|
80 |
+ event2.payload = { |
|
81 |
+ :content => { |
|
82 |
+ :text => "Some Lorem Ipsum", |
|
83 |
+ :name => "somevalue" |
|
84 |
+ }, |
|
85 |
+ :conditions => "someothervalue" |
|
86 |
+ } |
|
87 |
+ |
|
88 |
+ lambda { |
|
89 |
+ @checker.receive([event2,event1]) |
|
90 |
+ }.should change { Event.count }.by(2) |
|
91 |
+ end |
|
92 |
+ end |
|
93 |
+ |
|
94 |
+ describe "validation" do |
|
95 |
+ before do |
|
96 |
+ @checker.should be_valid |
|
97 |
+ end |
|
98 |
+ |
|
99 |
+ it "should validate presence of instructions" do |
|
100 |
+ @checker.options[:instructions] = "" |
|
101 |
+ @checker.should_not be_valid |
|
102 |
+ end |
|
103 |
+ |
|
104 |
+ it "should validate presence of mode" do |
|
105 |
+ @checker.options[:mode] = "" |
|
106 |
+ @checker.should_not be_valid |
|
107 |
+ end |
|
108 |
+ |
|
109 |
+ it "should validate presence of skip_agent" do |
|
110 |
+ @checker.options[:skip_agent] = "" |
|
111 |
+ @checker.should_not be_valid |
|
112 |
+ end |
|
113 |
+ |
|
114 |
+ it "should validate presence of skip_created_at" do |
|
115 |
+ @checker.options[:skip_created_at] = "" |
|
116 |
+ @checker.should_not be_valid |
|
117 |
+ end |
|
118 |
+ end |
|
119 |
+end |
@@ -0,0 +1,76 @@ |
||
1 |
+require 'spec_helper' |
|
2 |
+ |
|
3 |
+describe Agents::SentimentAgent do |
|
4 |
+ before do |
|
5 |
+ @valid_params = { |
|
6 |
+ :name => "somename", |
|
7 |
+ :options => { |
|
8 |
+ :content => "$.message", |
|
9 |
+ :expected_receive_period_in_days => 1 |
|
10 |
+ } |
|
11 |
+ } |
|
12 |
+ |
|
13 |
+ @checker = Agents::SentimentAgent.new(@valid_params) |
|
14 |
+ @checker.user = users(:jane) |
|
15 |
+ @checker.save! |
|
16 |
+ |
|
17 |
+ @event = Event.new |
|
18 |
+ @event.agent = agents(:jane_weather_agent) |
|
19 |
+ @event.payload = { |
|
20 |
+ :message => "value1" |
|
21 |
+ } |
|
22 |
+ @event.save! |
|
23 |
+ end |
|
24 |
+ |
|
25 |
+ describe "#working?" do |
|
26 |
+ it "checks if events have been received within expected receive period" do |
|
27 |
+ @checker.should_not be_working |
|
28 |
+ Agents::SentimentAgent.async_receive @checker.id, [@event.id] |
|
29 |
+ @checker.reload.should be_working |
|
30 |
+ two_days_from_now = 2.days.from_now |
|
31 |
+ stub(Time).now { two_days_from_now } |
|
32 |
+ @checker.reload.should_not be_working |
|
33 |
+ end |
|
34 |
+ end |
|
35 |
+ |
|
36 |
+ describe "validation" do |
|
37 |
+ before do |
|
38 |
+ @checker.should be_valid |
|
39 |
+ end |
|
40 |
+ |
|
41 |
+ it "should validate presence of content key" do |
|
42 |
+ @checker.options[:content] = nil |
|
43 |
+ @checker.should_not be_valid |
|
44 |
+ end |
|
45 |
+ |
|
46 |
+ it "should validate presence of expected_receive_period_in_days key" do |
|
47 |
+ @checker.options[:expected_receive_period_in_days] = nil |
|
48 |
+ @checker.should_not be_valid |
|
49 |
+ end |
|
50 |
+ end |
|
51 |
+ |
|
52 |
+ describe "#receive" do |
|
53 |
+ it "checks if content key is working fine" do |
|
54 |
+ @checker.receive([@event]) |
|
55 |
+ Event.last.payload[:content].should == "value1" |
|
56 |
+ Event.last.payload[:original_event].should == {:message => "value1"} |
|
57 |
+ end |
|
58 |
+ it "should handle multiple events" do |
|
59 |
+ event1 = Event.new |
|
60 |
+ event1.agent = agents(:bob_weather_agent) |
|
61 |
+ event1.payload = { |
|
62 |
+ :message => "The quick brown fox jumps over the lazy dog" |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ event2 = Event.new |
|
66 |
+ event2.agent = agents(:jane_weather_agent) |
|
67 |
+ event2.payload = { |
|
68 |
+ :message => "The quick brown fox jumps over the lazy dog" |
|
69 |
+ } |
|
70 |
+ |
|
71 |
+ lambda { |
|
72 |
+ @checker.receive([@event,event1,event2]) |
|
73 |
+ }.should change { Event.count }.by(3) |
|
74 |
+ end |
|
75 |
+ end |
|
76 |
+end |